﻿


using System;
using System.Collections.Generic;
using System.Windows;

namespace VtcPositionDemo.Models
{
    

    public class TData
    {
        #region
        public double X { get; set; }
        public double Y { get; set; }
        public string Lab { get; set; }

        public TData(double x, double y)
        {
            this.X = x;
            this.Y = y;
        }
        public TData(double x, double y, string lab)
        {
            this.X = x;
            this.Y = y;
            this.Lab = lab;
        }
        #endregion
    }

    public class CurvFormat : DependencyObject
    {
        public static DependencyProperty MinStepProperty;
        public double MinStep
        {
            #region
            get
            {
                return (double)GetValue(MinStepProperty);
            }
            set
            {
                SetValue(MinStepProperty, value);
            }
            #endregion
        }

        public event DependencyPropertyChangedEventHandler OnDependencyPropertyChanged;
        protected static void PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            #region
            CurvFormat mn = (CurvFormat)d;

            if (mn.OnDependencyPropertyChanged != null)
            {
                mn.OnDependencyPropertyChanged(d, e);
            }
            #endregion
        }

        static CurvFormat()
        {
            #region
            try
            {

                FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata(1.0);
                metadata.PropertyChangedCallback = new PropertyChangedCallback(PropertyChanged);
                CurvFormat.MinStepProperty = DependencyProperty.Register("MinStep", typeof(double), typeof(CurvFormat), metadata);
            }
            catch (Exception ee)
            {

            }
            #endregion
        }
    }
    public class Curv
    {
        #region
        public double vMax = 0;
        public double vMin = 0;
        public double hMax = 0;
        public double hMin = 0;
        public double vAxisMax = 0;
        public double vAxisMin = 0;
        public double hAxisMax = 0;
        public double hAxisMin = 0;
        public bool isWaitFirstPoint = true;
        public double startTime = 0;
        #endregion
    }
    public class RecordCenter : DependencyObject
    {
        public enum RecordState
        {
            Start,
            WaitTry,
            OnTry,
            Record,
            Hold,
            Stop
        }

        public class RecordData
        {
            public bool IsValid = false;
            public bool IsHead = false;
            public List<double> Times = new List<double>();
            public List<int> Ads = new List<int>();
        }

        public static DependencyProperty DoorValProperty;
        public double DoorVal
        {
            #region
            get
            {
                return (double)GetValue(DoorValProperty);
            }
            set
            {
                SetValue(DoorValProperty, value);
            }
            #endregion
        }

        public static DependencyProperty RecordTimeProperty;
        public int RecordTime
        {
            #region ms
            get
            {
                return (int)GetValue(RecordTimeProperty);
            }
            set
            {
                SetValue(RecordTimeProperty, value);
            }
            #endregion
        }

        public static DependencyProperty IsStopOnRecordTimeProperty;
        public bool IsStopOnRecordTime
        {
            #region 满屏时，记录停止
            get
            {
                return (bool)GetValue(IsStopOnRecordTimeProperty);
            }
            set
            {
                SetValue(IsStopOnRecordTimeProperty, value);
            }
            #endregion
        }

        public static DependencyProperty HoldTimeProperty;
        public int HoldTime
        {
            #region ms
            get
            {
                return (int)GetValue(HoldTimeProperty);
            }
            set
            {
                SetValue(HoldTimeProperty, value);
            }
            #endregion
        }

        public static DependencyProperty AcqFreqProperty;
        public int AcqFreq
        {
            #region
            get
            {
                return (int)GetValue(AcqFreqProperty);
            }
            set
            {
                SetValue(AcqFreqProperty, value);
            }
            #endregion
        }
        public static DependencyProperty RecDataProperty;
        public RecordData RecData
        {
            #region
            get
            {
                return (RecordData)GetValue(RecDataProperty);
            }
            set
            {
                SetValue(RecDataProperty, value);
            }
            #endregion
        }

        public static DependencyProperty RecStateProperty;
        public RecordState RecState
        {
            #region
            get
            {
                return (RecordState)GetValue(RecStateProperty);
            }
            private set
            {
                SetValue(RecStateProperty, value);
            }
            #endregion
        }

        public event DependencyPropertyChangedEventHandler OnDependencyPropertyChanged;
        protected static void PropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            #region
            RecordCenter mn = (RecordCenter)d;

            if (mn.OnDependencyPropertyChanged != null)
            {
                mn.OnDependencyPropertyChanged(d, e);
            }
            if (e.Property == RecordCenter.DoorValProperty)
            {
                mn.RecState = RecordState.Start;
            }
            #endregion
        }

        private int m_recordCount = 0;
        private double m_lastV = 0;
        private double m_timeMs = 0;
        private RecordData m_rData;
        private double m_holdT = 0;

        static RecordCenter()
        {
            #region
            try
            {

                FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata(0.0);
                metadata.PropertyChangedCallback = new PropertyChangedCallback(PropertyChanged);
                RecordCenter.DoorValProperty = DependencyProperty.Register("DoorVal", typeof(double), typeof(RecordCenter), metadata);

                metadata = new FrameworkPropertyMetadata(1000);
                metadata.PropertyChangedCallback = new PropertyChangedCallback(PropertyChanged);
                RecordCenter.RecordTimeProperty = DependencyProperty.Register("RecordTime", typeof(int), typeof(RecordCenter), metadata);

                metadata = new FrameworkPropertyMetadata(1000);
                metadata.PropertyChangedCallback = new PropertyChangedCallback(PropertyChanged);
                RecordCenter.HoldTimeProperty = DependencyProperty.Register("HoldTime", typeof(int), typeof(RecordCenter), metadata);

                metadata = new FrameworkPropertyMetadata(false);
                metadata.PropertyChangedCallback = new PropertyChangedCallback(PropertyChanged);
                RecordCenter.IsStopOnRecordTimeProperty = DependencyProperty.Register("IsStopOnRecordTime", typeof(bool), typeof(RecordCenter), metadata);

                metadata = new FrameworkPropertyMetadata(50);
                metadata.PropertyChangedCallback = new PropertyChangedCallback(PropertyChanged);
                RecordCenter.AcqFreqProperty = DependencyProperty.Register("AcqFreq", typeof(int), typeof(RecordCenter), metadata);

                metadata = new FrameworkPropertyMetadata();
                metadata.PropertyChangedCallback = new PropertyChangedCallback(PropertyChanged);
                RecordCenter.RecDataProperty = DependencyProperty.Register("RecData", typeof(RecordData), typeof(RecordCenter), metadata);

                metadata = new FrameworkPropertyMetadata(RecordState.Stop);
                metadata.PropertyChangedCallback = new PropertyChangedCallback(PropertyChanged);
                RecordCenter.RecStateProperty = DependencyProperty.Register("RecState", typeof(RecordState), typeof(RecordCenter), metadata);

            }
            catch (Exception ee)
            {

            }
            #endregion
        }
        public RecordCenter()
        {
            this.OnDependencyPropertyChanged += RecordCenter_OnDependencyPropertyChanged;
        }

        private void RecordCenter_OnDependencyPropertyChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            #region
            if (e.Property == RecordCenter.DoorValProperty)
            {
                if (this.RecState == RecordState.WaitTry)
                {
                    this.RecState = RecordState.Start;
                }
            }
            #endregion
        }

        private void PushData(int val, double interMs)
        {
            #region
            switch (this.RecState)
            {
                case RecordState.Start:
                    this.m_lastV = val;
                    this.RecState = RecordState.WaitTry;
                    break;
                case RecordState.WaitTry:
                    if (this.m_lastV >= this.DoorVal && val <= this.DoorVal || this.m_lastV <= this.DoorVal && val >= this.DoorVal) // 穿越触发
                    {
                        this.RecState = RecordState.OnTry;
                    }
                    break;
                case RecordState.OnTry:
                    this.RecState = RecordState.Record;
                    this.m_recordCount = 0;
                    this.m_timeMs = 0;
                    this.m_rData = new RecordData();
                    this.m_rData.IsValid = true;
                    this.m_rData.IsHead = true;
                    this.m_rData.Times.Add(this.m_timeMs);
                    this.m_rData.Ads.Add(val);
                    break;
                case RecordState.Record:
                    this.m_recordCount++;
                    this.m_rData.IsValid = true;
                    this.m_timeMs += interMs;
                    this.m_rData.Times.Add(this.m_timeMs);
                    this.m_rData.Ads.Add(val);
                    if (this.m_timeMs >= this.RecordTime)
                    {
                        if (this.IsStopOnRecordTime)
                        {
                            this.RecState = RecordState.Stop;
                        }
                        else
                        {
                            this.RecState = RecordState.Hold;
                            this.m_holdT = 0;
                        }
                    }
                    break;
                case RecordState.Hold:
                    this.m_holdT += interMs;
                    if (this.m_holdT >= this.HoldTime)
                    {
                        this.RecState = RecordState.OnTry;
                    }
                    break;
            }
            #endregion
        }

        public void Start()
        {
            #region
            this.RecState = RecordState.Start;
            #endregion
        }

        public void Stop()
        {
            #region
            this.RecState = RecordState.Stop;
            #endregion
        }

        public void Push(int[] ads, int adsLen)
        {
            #region
            this.m_rData = new RecordData();
            var allNum = (int)(this.AcqFreq * (this.RecordTime / 1000));   // 转换成秒，获取该时间段内所有点数
            int inter = 1;
            if (allNum > 10000) // 最多画1万个点
            {
                inter = (int)Math.Ceiling(allNum / 10000.0);
            }
            var dms = inter * 1000.0 / this.AcqFreq;
            for (int i = 0; i < adsLen; i += inter)
            {
                this.PushData(ads[i], dms);
            }
            if (this.m_rData.IsValid)
            {
                this.RecData = this.m_rData;
            }
            #endregion
        }
    }


    class Model
    {
   
   

        public static void Close()
        {
            #region
      
            #endregion
        }



        public static double FitGreaterRule(double val, double rule, double disE)
        {
            #region 计算一个最接近该数的以rule结尾的数据, val,rule和disE都必须是正数
            double step = rule;
            string str = rule.ToString();
            int dot = 0;
            int index = str.IndexOf(".");
            if (index >= 0)
            {
                dot = str.Length - index - 1;
            }
            while (step > val)
            {
                step = step / 10.0;
            }
            double nv = step;
            while (nv < val)
            {
                nv += step;
            }
            if (disE == 0)
            {
                return nv;
            }
            if (nv > val + disE)
            {
                return FitGreaterRule(val, rule * 0.1, disE);
            }
            return nv;
            #endregion
        }

        public static double FitGreaterRule(double val, double rule, int stepDot)
        {
            #region 计算一个最接近该数的以rule结尾的数据, val,rule和stepDot都必须是正数
            double step = rule;
            string str = rule.ToString();
            int dot = 0;
            int index = str.IndexOf(".");
            if (index >= 0)
            {
                dot = str.Length - index - 1;
            }
            while (step > val && dot < stepDot)
            {
                step = step / 10.0;
                dot++;
            }
            double nv = step;
            while (nv < val)
            {
                nv += step;
            }
            return nv;
            #endregion
        }

        public static double FitLessRule(double val, double rule, int stepDot)
        {
            #region 计算一个最接近该数的以rule结尾的数据,val,rule和stepDot都必须是正数
            double step = rule;
            string str = rule.ToString();
            int dot = 0;
            int index = str.IndexOf(".");
            if (index >= 0)
            {
                dot = str.Length - index - 1;
            }
            while (step > val && dot < stepDot)
            {
                step = step / 10.0;
                dot++;
            }
            double nv = step;
            while (nv < val)
            {
                nv += step;
            }
            nv -= step;
            return nv;
            #endregion
        }

        public static double FitLessRule(double val, double rule, double disE)
        {
            #region 计算一个最接近该数的以rule结尾的数据,val,rule和disE都必须是正数
            double step = rule;
            while (step > val)
            {
                step = step / 10.0;
            }
            double nv = step;
            while (nv < val)
            {
                nv += step;
            }
            nv -= step;
            if (disE == 0)
            {
                return nv;
            }
            if (nv < val - disE)
            {
                return FitLessRule(val, rule * 0.1, disE);
            }
            return nv;
            #endregion
        }

        public static double FitLessBorder(double val, double amp)
        {
            #region 计算一个比val小的最好看的边界值，边界值范围在amp之间,amp必须是正数
            double minV = val - amp;
            if (minV * val <= 0)
            {
                return 0;
            }
            if (amp == 0)
            {
                return val;
            }

            char[] cc = { '0', '5', '4', '2', '8', '6', '3', '9', '7' };
            string vs = val.ToString();
            var os = vs.ToCharArray();
            var zeros = vs.ToCharArray();

            int start = 0;
            if (val < 0)
            {
                start = 1;
            }
            for (int i = start; i < zeros.Length; i++)
            {
                if (zeros[i] != '.')
                {
                    zeros[i] = '0';
                }
            }
            for (int i = start; i < zeros.Length; i++)
            {
                if (zeros[i] != '.')
                {
                    #region 找最合适的坐标
                    for (int j = 0; j < cc.Length; j++)
                    {
                        zeros[i] = cc[j];
                        string ns = "";
                        for (int n = 0; n < zeros.Length; n++)
                        {
                            ns += zeros[n];
                        }
                        double nv = double.Parse(ns);
                        if (nv <= val && nv > minV)
                        {
                            return nv;
                        }
                    }
                    #endregion

                    #region 如果没有，就确定i的数
                    zeros[i] = os[i];
                    if (true)
                    {
                        #region 进阶
                        string js = "1";
                        for (int x = start; x < zeros.Length; x++)
                        {
                            if (x == i)
                            {
                                js += "1";
                            }
                            else if (zeros[x] != '.')
                            {
                                js += "0";
                            }
                            else
                            {
                                js += zeros[x];
                            }
                        }
                        double jv = double.Parse(js);

                        string ns = "";
                        for (int n = 0; n < zeros.Length; n++)
                        {
                            ns += zeros[n];
                        }
                        double nv = double.Parse(ns);

                        double jnv = nv - jv;
                        if (jnv > minV)
                        {
                            return jnv;
                        }
                        #endregion
                    }
                    #endregion
                }
            }
            return val;
            #endregion
        }
        public static double FitGreaterBorder(double val, double amp)
        {
            #region 计算一个比val大的最好看的边界值，边界值范围在amp之间,amp必须是正数
            double maxV = val + amp;
            if (maxV * val <= 0)
            {
                return 0;
            }
            if (amp == 0)
            {
                return val;
            }

            char[] cc = { '0', '5', '4', '2', '8', '6', '3', '9', '7' };
            string vs = val.ToString();
            var os = vs.ToCharArray();
            var zeros = vs.ToCharArray();

            int start = 0;
            if (val < 0)
            {
                start = 1;
            }
            for (int i = start; i < zeros.Length; i++)
            {
                if (zeros[i] != '.')
                {
                    zeros[i] = '0';
                }
            }
            for (int i = start; i < zeros.Length; i++)
            {
                if (zeros[i] != '.')
                {
                    #region 找最合适的坐标
                    for (int j = 0; j < cc.Length; j++)
                    {
                        zeros[i] = cc[j];
                        string ns = "";
                        for (int n = 0; n < zeros.Length; n++)
                        {
                            ns += zeros[n];
                        }
                        double nv = double.Parse(ns);
                        if (nv >= val && nv < maxV)
                        {
                            return nv;
                        }
                    }
                    #endregion

                    #region 如果没有，就确定i的数
                    zeros[i] = os[i];
                    if (true)
                    {
                        #region 进阶
                        string js = "";
                        for (int x = start; x < zeros.Length; x++)
                        {
                            if (x == i)
                            {
                                js += "1";
                            }
                            else if (zeros[x] != '.')
                            {
                                js += "0";
                            }
                            else
                            {
                                js += zeros[x];
                            }
                        }
                        double jv = double.Parse(js);

                        string ns = "";
                        for (int n = 0; n < zeros.Length; n++)
                        {
                            ns += zeros[n];
                        }
                        double nv = double.Parse(ns);

                        double jnv = nv + jv;
                        if (jnv < maxV)
                        {
                            return jnv;
                        }
                        #endregion
                    }
                    #endregion
                }
            }
            return val;
            #endregion
        }

        public static double GetPrec(int dot)
        {
            #region
            double prec = 1.0;
            while (dot > 0)
            {
                prec *= 0.1;
                dot--;
            }
            return prec;
            #endregion
        }


        public static int PciCardInfo2Id(int[] info)
        {
            #region
            int[] seeds = {
                12345, 50214, 48902, 74329, 18427,
                75209, 38923, 19328, 97548, 74824 };

            int sum = 0;
            for (int i = 0; i < 6; i++)
            {
                sum += (info[i] & 0x7fff);
            }
            int seed = seeds[sum % 10];
            return (((seed * sum + info[1]) & 0x7fffffff) % 1000000);
            #endregion
        }

        public static int ReverseNumber6(int n)
        {
            #region
            n = (n % 1000000);
            int rev = 0;
            for (int i = 0; i < 6; i++)
            {
                rev = rev * 10 + (n % 10);
                n /= 10;
            }
            return (rev);
            #endregion
        }

        public static int ShiftRight6(int n, int right)
        {
            #region
            n = (n % 1000000);
            for (int i = 0; i < right; i++)
            {
                n = n / 10 + (n % 10) * 100000;
            }
            return (n);
            #endregion
        }

        public static int ShiftLeft6(int n, int left)
        {
            #region
            n = (n % 1000000);
            for (int i = 0; i < left; i++)
            {
                n = (n % 100000) * 10 + (n / 100000);
            }
            return (n);
            #endregion
        }

        /*
        licCode 0: full license
        else: smn: startMonth(sm): start month from 2000
                   limitMonth(n):  n *3 from startMonth

        WARNING: licCode==0 is not a good code, use sm0, in which sm=10+(mid%10)*3
        */
        public static int GetRegisterCode(int mid, int licCode)    //mid:机器号,licCode：注册状态，得到注册码
        {
            #region
            if (licCode == 0)
            {					// Bad
                int mid1 = (mid % 1000000);
                int mid2 = ReverseNumber6(mid / 10);
                return ((mid1 + mid2) * 10);
            }
            else
            {
                int startMonth = licCode / 10;
                int limitMonth = (licCode % 10);
                int shift = (limitMonth == 0 ? (mid % 10) * 2 / 3 : limitMonth);
                int mid1 = ShiftLeft6(mid % 1000000, shift);
                int mid2 = ReverseNumber6(mid1);
                return ((mid2 + startMonth * 10101) * 10 + limitMonth);
            }
            #endregion
        }

        public static int GetLicenseCode(int mid, int regCode) // mid:机器号,regCode:注册码,得到注册状态
        {
            #region
            int limitMonth = (regCode % 10);
            if (limitMonth == 0)
            {					// compatible with old method
                int rightRegCode = GetRegisterCode(mid, 0);
                if (rightRegCode == regCode)
                {
                    return (0);
                }
            }

            int shift = (limitMonth == 0 ? (mid % 10) * 2 / 3 : limitMonth);
            int mid1 = ShiftLeft6(mid % 1000000, shift);
            int mid2 = ReverseNumber6(mid1);
            int reg1 = regCode / 10;
            int d = (reg1 - mid2);
            if ((d % 10101) == 0)
            {
                int startMonth = d / 10101;
                if (limitMonth == 0)
                {				// check specific startMonth
                    return (startMonth == (10 + (mid % 10) * 3) ? 0 : -1);
                }
                else
                {
                    return (startMonth * 10 + limitMonth);
                }
            }
            return (-1);
            #endregion
        }

        /*
        ** month here is months from the first month of every 5 years
        ** ex: 2000.1 : 1
               2001.2 : 1*12+2=12
               2004.12: 4*12+12=60
               2005.1 : 1
        ** so month=[1, 60]
        */
    }

}
